import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
  Inject,
  Logger,
} from '@nestjs/common';
import { Request, Response } from 'express';

@Catch()
export class HttpExceptionFilter<T> implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    // HttpException 属于基础异常类，可自定义内容
    // 如果是自定义的异常类则抛出自定义的status
    // 否则就是内置的http异常类，然后抛出其对应的内置status
    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    // 抛出错误信息
    const errorList: any = exception.getResponse();

    let validatorMessage = errorList;

    if (Object.prototype.toString.call(errorList).includes('Array')) {
      validatorMessage = errorList.message[0];
    }

    if (Object.prototype.toString.call(errorList).includes('Object')) {
      validatorMessage = errorList.message
        ? errorList.message
        : Object.values(errorList).toString();
    }

    const message = validatorMessage || exception.message || null;
    const msgLog = {
      code: status, // 系统错误状态
      timestamp: new Date().toLocaleString(), // 错误时间
      path: request.url, // 错误路由
      msg: message,
      data: null, // 错误信息内容（争取和拦截器中定义的响应体一样）
    };

    Logger.error(`
      url: ${request.url}
      参数：${JSON.stringify(
        ['POST', 'PUT'].includes(request.method) ? request.body : request.query,
      )}
      响应：${JSON.stringify(message)}
    `);
    // response.status(status).json(msgLog);

    // 前后端约定接口通就是 200，其他状态码使用 code 判断
    response.status(200).json(msgLog);
  }
}
